package com.epro.dx.util;

import com.epro.dx.R;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

public class CreditCardCheckUtils {
	private final static int [] MasterCardLength={16};
	private final static int [] VISALength={13,16};
	private final static int [] AmericanExpressLength={15};
	private final static int [] UnionPayLength={16, 17, 18, 19};
	private final static int [] DinersClubLength={14, 16};
	private final static int [] enRouteLength={15};
	private final static int [] DiscoverLength={16};
	private final static int [] JCBLength={16};
	
	private final static int [] LaserLength={16, 17, 18, 19};
	private final static int [] MaestroLength={12, 13, 14, 15, 16, 17, 18, 19};
	
	
	private final static String [] MasterCardStart={"51", "52", "53", "54", "55"};
	private final static String [] VISAStart={"4026", "417500", "4508", "4844", "4913", "4917", "4"};
	private final static String [] AmericanExpressStart={"34", "37"};
	private final static String [] UnionPayStart={"62"};
	private final static String [] DinersClub14Start={"300", "301", "302", "303", "304", "305", "36"};
	private final static String [] DinersClub16Start={"54", "55"};
	private final static String [] enRouteStart={"2014", "2149"};
	//Discover 除掉以下开头的 还有开头numPre > 622125 && numPre < 622926
	private final static String [] DiscoverStart={"6011", "644", "645", "646", "647", "648", "649", "65"};
	
	private final static String [] LaserStart={"6304", "6706", "6771", "6709"};
	private final static String [] MaestroStart={"5018", "5020", "5038", "6304", "6759", "6761", "6762", "6763"};
    
    
    /**
     * 卡类型枚举
     */
    public static enum CardType{
    	Unknown,
        MasterCard,
        VISA,
        AmericanExpress,
        UnionPay,
        DinersClub,
        enRoute,
        Discover,
        JCB,
        Laser,
        Maestro,
        Solo,
        Switch
    }
    
    /**
     * 校验输入卡号是否为数字，
     * @param cardNumber
     * @return
     */
	private static boolean check(String cardNumber) {
		if(TextUtils.isEmpty(cardNumber)){
			return false;
		}
		if (!TextUtils.isDigitsOnly(cardNumber)) {
			return false;
		}
//		Log.i("TypeLog", "check "+cardNumber);
		int ca = 0, sum = 0, mul = 1, len = cardNumber.length();
		while ((--len) > -1) {
			ca = Integer.parseInt(cardNumber.charAt(len) + "", 10) * mul;
			sum += ca - (ca > 9 ? 9 : 0);
			// 1 <--> 2 toggle
			mul = 3 - mul;
		}
		return (sum % 10 == 0) && (sum > 0);
	}
    
    /**
     * 根据卡号获取卡类型
     * @param cardNumber 卡号
     * @return
     */
    public static CardType getBankCardType(String cardNumber,boolean isToast,Context context){
    	CardType cardType=CardType.Unknown;
    	if(null==cardNumber||"".equals(cardNumber)){
    		return cardType;
    	}
//    	Log.i("TypeLog", check(cardNumber)+" getBankCardType "+cardNumber);
        if (check(cardNumber)) {
            if (isLengthEqualArray(cardNumber, MasterCardLength)&&isStartWithArray(cardNumber,MasterCardStart)) {
                cardType = CardType.MasterCard;
            } else if (isLengthEqualArray(cardNumber, VISALength)&&isStartWithArray(cardNumber,VISAStart)) {
                cardType = CardType.VISA;
            } else if (isLengthEqualArray(cardNumber, UnionPayLength)&&isStartWithArray(cardNumber,UnionPayStart)) {
                cardType = CardType.UnionPay;
            } else if (isLengthEqualArray(cardNumber, AmericanExpressLength)&&isStartWithArray(cardNumber,AmericanExpressStart)) {
                cardType = CardType.AmericanExpress;
            } else if (isLengthEqualArray(cardNumber, DinersClubLength)&&(isStartWithArray(cardNumber,DinersClub14Start)||isStartWithArray(cardNumber,DinersClub16Start))) {//DinersClube卡 不同长度的开头号不一样 区分处理
                if(cardNumber.length()==14){
                	if(isStartWithArray(cardNumber,DinersClub14Start)){
                		cardType = CardType.DinersClub;
                	}
                }else if(cardNumber.length()==16){
                	if(isStartWithArray(cardNumber,DinersClub16Start)){
                		cardType = CardType.DinersClub;
                	}
                }
            }
            else if (isLengthEqualArray(cardNumber, enRouteLength)&&isStartWithArray(cardNumber,enRouteStart)) {
                cardType = CardType.enRoute;
            } else if (isLengthEqualArray(cardNumber, DiscoverLength)&&(isStartWithArray(cardNumber,DiscoverStart)||isDiscover(cardNumber))) {
               if(isStartWithArray(cardNumber,DiscoverStart)){
            	   cardType = CardType.Discover;
               }else{
            	   if(isDiscover(cardNumber)){
            		   cardType = CardType.Discover; 
            	   }
               }
            } else if (isLengthEqualArray(cardNumber, JCBLength)&&isJBC(cardNumber)) {
                cardType = CardType.JCB;
            } else if (isLengthEqualArray(cardNumber, LaserLength)&&isStartWithArray(cardNumber,LaserStart)) {
                cardType = CardType.Laser;
            } else if (isLengthEqualArray(cardNumber, MaestroLength)&&isStartWithArray(cardNumber,MaestroStart)) {
                cardType = CardType.Maestro;
            }
        }else{
        	if(isToast){
        		Toast.makeText(context, context.getString(R.string.invalid_card_sug), 0);
        	}
        }
        return cardType;
    }
    
    /**
     * 判断是否输入卡号与指定卡开始字符相同
     * @param cardNumber 输入的卡号
     * @param cardStartWith 指定卡类型开始字符
     * @return
     */
    private static boolean isStartWithArray(String cardNumber,String[] cardStartWith){
    	int length=cardStartWith.length; //指定卡 开始字符类型个数
    	for(int i=0;i<length;i++){
    		if(cardNumber.startsWith(cardStartWith[i])){
    			return true;
    		}
    	}
    	return false;
    }
    
    /**
     * 判断是否输入卡号长度与指定卡长度相同
     * @param cardNumber 输入的卡号
     * @param cardStartWith 指定卡类型长度
     * @return
     */
    private static boolean isLengthEqualArray(String cardNumber,int[] cardLength){
//    	Log.i("TypeLog", cardNumber+" array "+cardLength.length);
    	int length=cardNumber.length();//输入卡号长度
    	int carLen=cardLength.length;//指定卡长度类型个数
    	for(int i=0;i<carLen;i++){
    		if(length==cardLength[i]){
    			return true;
    		}
    	}
    	return false; 
    }
    
    /**
     * 判断是否为JBC卡类型
     * @param cardNumber
     * @return
     */
    private static boolean isJBC(String cardNumber){
    	 if (cardNumber.indexOf("35") == 0) {
             int numPre = Integer.parseInt(cardNumber.substring(0, 4), 10);
             return numPre > 3527 && numPre < 3590;
         }
    	 return false;
    }
    
    /**
     * 判断是否为Discover类型
     * @param cardNumber 卡号
     * @return
     */
    private static boolean isDiscover(String cardNumber){
            int numPre = Integer.parseInt(cardNumber.substring(0, 6), 10);
           return (numPre > 622125 && numPre < 622926);
    }
}
